package com.budwk.app.sqfw.component;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.jim.WebSocketMsgDTO;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.constants.SqfwWebSocketMsgConstants;
import com.budwk.app.sqfw.dto.SqfwCompleteFlowUpdateDTO;
import com.budwk.app.sqfw.dto.SqfwFormSummaryWithFlowDTO;
import com.budwk.app.sqfw.enums.DownLoadFileNameEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_completeflow;
import com.budwk.app.sqfw.models.Sqfw_formSummary;
import com.budwk.app.sqfw.services.SqfwCompleteflowService;
import com.budwk.app.sqfw.services.SqfwDownRecordlogService;
import com.budwk.app.sqfw.services.SqfwFormSummaryService;
import com.budwk.app.sqfw.services.impl.SqfwSummaryForAdminServiceImpl;
import com.budwk.app.sqfw.vo.AreaAddressVo;
import com.budwk.app.sqfw.vo.Sqfw_formSummaryForAdminVO;
import com.budwk.app.sqfw.vo.SysDictResVo;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.AuthorityUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeForAdminUtils;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.security.utils.SecurityUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.util.*;
import java.util.stream.Collectors;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.addWordPicture;

/**
 * 会议记录公共类
 */

@Slf4j
@IocBean
public class MeetingMinutesComponent {

    @Inject
    private SysUserService sysUserService;
    @Inject
    private SqfwFormSummaryService sqfwFormSummaryService;
    @Inject
    private SqfwCompleteflowService sqfwCompleteflowService;
    @Inject
    private SysDictService sysDictService;
    @Inject
    private FromSummaryComponent fromSummaryComponent;
    @Inject
    private SqfwDownRecordlogService sqfwDownRecordlogService;


    /**
     * 后台列表公共查询参数设置
     *
     * @param forAdminVo
     * @return
     */
    public Criteria buildQueryCond(Sqfw_formSummaryForAdminVO forAdminVo) {
        Criteria cri = Cnd.cri();
        SqlExpressionGroup expressionSql = cri.where();
        AreaAddressVo areaAddressVo = AuthorityUtil.checkFormSummaryAreaPermission(forAdminVo);
        // 公共查询
        AuthorityUtil.commonPermissionLikeQuery(expressionSql, areaAddressVo);
        // 组装查询条件
        if (StringUtils.isNotBlank(forAdminVo.getPageOrderName()) && StringUtils.isNotBlank(forAdminVo.getPageOrderBy())) {
            if (forAdminVo.getPageOrderBy().equals(CommonConstants.ASC)) {
                cri.getOrderBy().asc(forAdminVo.getPageOrderName());
            }
            if (forAdminVo.getPageOrderBy().equals(CommonConstants.DESC)) {
                cri.getOrderBy().desc(forAdminVo.getPageOrderName());
            }
        } else {
            cri.getOrderBy().desc(Sqfw_formSummary::getCreateDate);
        }
        expressionSql.andEquals(Sqfw_formSummary::getType, SupportBusinessTypeEnum.MEET_RECORD.getName());
        // 会议时间
        CommunityStreetComponent.handleFillQueryTime(forAdminVo, expressionSql);
        // 提交时间
        CommunityStreetComponent.handleQueryTime(forAdminVo, expressionSql);
        // 会议名称 a20
        if (StringUtils.isNotBlank(forAdminVo.getA20())) {
            expressionSql.andLike(Sqfw_formSummary::getA20, forAdminVo.getA20());
        }
        // 会议地点】取值a3
        if (StringUtils.isNotBlank(forAdminVo.getA3())) {
            expressionSql.andLike(Sqfw_formSummary::getA3, forAdminVo.getA3());
        }
        // 提交人
        if (StringUtils.isNotBlank(forAdminVo.getCreateUserName())) {
            expressionSql.andLike(Sqfw_formSummary::getCreateUserName, forAdminVo.getCreateUserName());
        }
        if (StringUtils.isNotBlank(forAdminVo.getQueryAll())) {
            String queryAll = forAdminVo.getQueryAll();
            SqlExpressionGroup a20 = Cnd.exps(Sqfw_formSummaryForAdminVO::getA20, "like", "%" + queryAll + "%");
            SqlExpressionGroup a3 = Cnd.exps(Sqfw_formSummaryForAdminVO::getA3, "like", "%" + queryAll + "%");
            SqlExpressionGroup createUserName = Cnd.exps(Sqfw_formSummaryForAdminVO::getCreateUserName, "like", "%" + queryAll + "%");
            expressionSql.and(a20.or(a3).or(createUserName));
        }
        // 如果是查询未超时数据，只查询7天前的数据（需求）
        if (StringUtils.isNotBlank(forAdminVo.getCheckStatus()) && SqfwSummaryForAdminServiceImpl.TO_DO_CHECK_OUT.equals(forAdminVo.getCheckStatus())) {
            expressionSql.andEquals(Sqfw_formSummary::getCheckStatus, forAdminVo.getCheckStatus());
            Date offsetDate = DateUtil.parse(CommonFormOfficeForAdminUtils.DATE_FORMAT.format(DateUtil.offsetDay(new Date(), -CommonFormOfficeForAdminUtils.TIME_OUT)));
            expressionSql.and(Sqfw_formSummary::getFillDate, "<", offsetDate);
        }
        return cri;
    }

    /**
     * Excel会议记录台账
     *
     * @param sqfwId 社区服务id
     * @return url
     */
    public String generateMeetExcelLedger(String sqfwId) {
        // 1 查询数据
        Criteria cri = Cnd.cri();
        SqlExpressionGroup criSql = cri.where();
        criSql.andEquals(Sqfw_formSummary::getSqfwId, sqfwId).andEquals(Sqfw_formSummary::getType, SupportBusinessTypeEnum.MEET_RECORD.getName());
        List<Sqfw_formSummary> formSummaryList = sqfwFormSummaryService.query(cri);
        if (formSummaryList == null || formSummaryList.size() == 0) {
            throw new AppException("请先添加任务！！");
        }
        //String fileName = String.format("%s%s%s", "Excel", "会议记录台账", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        //zhangp 2023-12-13 文件名称格式统一
        // 2 检查是否存在数据
        String meetExcel = CommonComponent.getMeetRecordTypes().get(DictConstants.MEET_RECORD_TYPES_EXCEL);
        String title = String.format("%s%s", "下载", meetExcel);
        String ids = formSummaryList.stream().map(Sqfw_formSummary::getId).collect(Collectors.joining(""));
        Optional<String> optional = sqfwDownRecordlogService.getUrlByEntityIdAndTitle(ids, title);
        if (optional.isPresent()) {
            log.info("generateMeetExcelLedger res: {}", optional.get());
            return optional.get();
        }
        // 3 生成台账
        String url = generateExcelFile(formSummaryList, null);
        CommonComponent.insertDownRecordLog(sqfwId, JSONObject.toJSONString(Result.data(url)), title, url, ids);
        return url;
    }


    /**
     * 上传台账内容
     *
     * @param formSummaryList
     * @return
     */
    public String generateExcelFile(List<Sqfw_formSummary> formSummaryList, String isCheckData) {
        // 1 构建内容体
        Sys_user user = sysUserService.fetch(SecurityUtil.getUserId());
        Map<String, Object> excelMap = new HashMap<>();
        excelMap.put("Street", user.getCounty());
        List<Map<String, Object>> dataList = Lists.newArrayList();
        int num = 1;
        for (Sqfw_formSummary formSummary : formSummaryList) {
            Map<String, Object> dataMap = fromSummaryComponent.buildContent(formSummary, num, SupportBusinessTypeEnum.MEET_RECORD.getName());
            // 图片处理
            if (StringUtils.isNotEmpty(formSummary.getA9())) {
                String[] a9s = formSummary.getA9().split(",");
                dataMap.put("a9", CommonFormOfficeUtils.addPictureToByteList(formSummary.getA9(), a9s.length));
            }
            dataList.add(dataMap);
            num++;

        }
        if (StringUtils.isNotBlank(isCheckData) && isCheckData.equals("isCheckData")) {
            if (dataList.isEmpty()) {
                return "false";
            } else {
                return "true";
            }
        }
        excelMap.put("list", dataList);
        //zhangp  名称统一为
        String fileName = DownLoadFileNameEnum.MEETING_RECORD.getName();

        // 2 上传文档
        String url = FromSummaryComponent.generateExcelLedger(excelMap, "meetingMinutes/meeting_minutes_ledger_template.xlsx",
                fileName, SupportBusinessTypeEnum.MEET_RECORD.getName());
        log.info("statisticalExcelLedger info res: {}", url);
        return url;
    }

    /**
     * 生成PDF会议记录集合
     *
     * @param sqfwId 社区服务iD
     * @return url
     */
    public String generatePDFMeetingRecordCollection(String sqfwId) {
        // 1 查询数据
        Criteria cri = Cnd.cri();
        SqlExpressionGroup criSql = cri.where();
        criSql.andEquals(Sqfw_completeflow::getSqfwId, sqfwId).andEquals(Sqfw_completeflow::getFileType, SupportBusinessTypeEnum.MEET_RECORD.getName());
        List<Sqfw_completeflow> completeFlowList = sqfwCompleteflowService.query(cri);
        if (completeFlowList.size() == 0) throw new AppException("请先添加任务！！");;
        // 如果存在下载历史 直接下载
        String ids = completeFlowList.stream().map(Sqfw_completeflow::getId).collect(Collectors.joining(""));

        String meetPDF = CommonComponent.getMeetRecordTypes().get(DictConstants.MEET_RECORD_TYPES_PDF);
        String title = String.format("%s%s", "下载", meetPDF);
        Optional<String> optional = sqfwDownRecordlogService.getUrlByEntityIdAndTitle(ids, title);
        if (optional.isPresent()) {
            log.info("generatePDFMeetingRecordCollection res: {}", optional.get());
            return optional.get();
        }
        // 2 组装pdf数据集合
        List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());
        //String fileName = String.format("%s%s%s", "pdf", ServiceTypeEnum.MEETING_RECORD.getName(), "整治表集合");
        //zhangp 2023-12-13 文件名称格式统一
        String fileName = DownLoadFileNameEnum.MEETING_RECORD_PDF.getName();

        String url = CommonFormOfficeUtils.createConvergePdfAndUpload(pdfList, fileName);
        log.info("generatePDFMeetingRecordCollection res: {}", url);
        CommonComponent.insertDownRecordLog(sqfwId, JSONObject.toJSONString(Result.data(url)), title, url, ids);
        return url;
    }

    /**
     * 提交任务时生成pdf
     *
     * @param completeFlow 任务流
     * @param formSummary  表信息
     */
    public void generatePDF(Sqfw_completeflow completeFlow, Sqfw_formSummary formSummary) {
        Map<String, Object> conentMap = fromSummaryComponent.buildContent(formSummary, 1, SupportBusinessTypeEnum.MEET_RECORD.getName());
        // 图片处理
        if (StringUtils.isNotEmpty(formSummary.getA9())) {
            conentMap.put("a9s", addWordPicture(formSummary.getA9(), "a9", 8F));
        }
        WebSocketMsgDTO msgDTO = new WebSocketMsgDTO();
        msgDTO.setType(SqfwWebSocketMsgConstants.WORK_FORM_MEET_RECORD_PDF_RECREATED);
        msgDTO.setMsg("会议记录表PDF生成成功");
        String fileName;
        if (StringUtils.isNotEmpty(formSummary.getA20())) {
            //fileName = String.format("%s-%s-%s", formSummary.getA20(), ServiceTypeEnum.MEETING_RECORD.getName(), DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
            //zhangp 2023-12-13 文件名称格式统一
            String downloadFileName = DownLoadFileNameEnum.MEETING_RECORD_PDF.getName();
            fileName = String.format("%s-%s-%s", formSummary.getA20(), downloadFileName, DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        } else {
            //fileName = "会议记录表集合";
            //zhangp 2023-12-13 文件名称格式统一
            fileName = DownLoadFileNameEnum.MEETING_RECORD_PDF.getName();
        }
        fromSummaryComponent.generatePDF(SecurityUtil.getUserId(), completeFlow.getId(), conentMap, "meetingMinutes/meeting_minutes_template.docx", fileName, msgDTO);
    }

    /**
     * 校验提交会议时基本入参
     *
     * @param reqVo 请求参数
     */
    public void checkAddMeetParam(SqfwFormSummaryWithFlowDTO reqVo) {
        Sqfw_formSummary formSummary = reqVo.getFormSummary();
        SqfwCompleteFlowUpdateDTO completeFlow = reqVo.getCompleteFlow();
        if (formSummary == null || completeFlow == null) {
            throw new AppException("基本参数为空!");
        }
        String[] columns = {formSummary.getA20(), formSummary.getA3(), formSummary.getA18(), completeFlow.getSqfwId(), completeFlow.getWorkerId()};
        String[] columnValues = {"会议名称[a20]为空!", "会议地点[a3]为空!", "讨论事项[a18]为空!", "服务id为空!", "工作流id为空！"};
        for (int i = 0; i < columns.length; i++) {
            if (StringUtils.isEmpty(columns[i])) {
                throw new AppException(columnValues[i]);
            }
        }
    }

    public List<SysDictResVo> listDownFileTypes(String sqfwId) {
        // 获取 会议记录下载文档类型
        Sys_dict sysDict = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", "meeting_minutes_download_document_type"));
        if (sysDict == null) {
            throw new AppException("请联系管理员先添加数据字典项！");
        }
        List<Sys_dict> list = sysDictService.query(Cnd.where(Sys_dict::getParentId, "=", sysDict.getId()));
        // 检查当前操作人是否存在数据
        Criteria cri = Cnd.cri();
        SqlExpressionGroup criSql = cri.where();
        criSql.andEquals(Sqfw_formSummary::getCreateBy, SecurityUtil.getUserId())
                .andEquals(Sqfw_formSummary::getType, SupportBusinessTypeEnum.MEET_RECORD.getName())
                .andEquals(Sqfw_formSummary::getSqfwId, sqfwId);
        int count = sqfwFormSummaryService.count(cri);
        List<SysDictResVo> results = new ArrayList<>();
        for (Sys_dict sys_dict : list) {
            SysDictResVo dictResVo = new SysDictResVo();
            BeanUtil.copyProperties(sys_dict, dictResVo);
            dictResVo.setData(count > 0);
            results.add(dictResVo);
        }
        return results;
    }
}
